package top.suyarong.ftbqsync.utils;

import org.bukkit.entity.Player;
import top.suyarong.ftbqsync.FTBQSync;

import java.lang.reflect.Method;
import java.util.Objects;

public class FTBQuestUtil {

    private static final Class<?> SERVER_QUEST_DATA;

    private static final Method SERVER_QUEST_DATA_GET;

    private static final Method SERVER_QUEST_DATA_MARK_DIRTY;

    private static final Method SERVER_QUEST_DATA_READ_DATA;
    private static final Method SERVER_QUEST_DATA_WRITE_DATA;

    private static final LogUtil log = LogUtil.getInstance();

    private static final FTBQSync plugin = FTBQSync.getInstance();

    public static final String UTIL_NAME = "FTBQuestUtil ===> {0} 载入完成";

    static {

        SERVER_QUEST_DATA = ReflectionUtil.getClass("com.feed_the_beast.ftbquests.util.ServerQuestData");
        log.debug(plugin, UTIL_NAME, SERVER_QUEST_DATA.getName());

        SERVER_QUEST_DATA_GET = ReflectionUtil.getSingleParamMethod(SERVER_QUEST_DATA, "get", FTBLibUtil.FTB_TEAM.getType());
        log.debug(plugin, UTIL_NAME, SERVER_QUEST_DATA_GET.getDeclaringClass().getName() + "." + SERVER_QUEST_DATA_GET.getName() + "()");

        SERVER_QUEST_DATA_MARK_DIRTY = ReflectionUtil.getUnknownMethod(SERVER_QUEST_DATA, "markDirty");
        log.debug(plugin, UTIL_NAME, SERVER_QUEST_DATA_MARK_DIRTY.getDeclaringClass().getName() + "." + SERVER_QUEST_DATA_MARK_DIRTY.getName() + "()");

        SERVER_QUEST_DATA_READ_DATA = ReflectionUtil.getSingleParamMethod(SERVER_QUEST_DATA, "readData", NMSUtil.NBT_TAG_COMPOUND);
        log.debug(plugin, UTIL_NAME, SERVER_QUEST_DATA_READ_DATA.getDeclaringClass().getName() + "." + SERVER_QUEST_DATA_READ_DATA.getName() + "()");

        SERVER_QUEST_DATA_WRITE_DATA = ReflectionUtil.getSingleParamMethod(SERVER_QUEST_DATA, "writeData", NMSUtil.NBT_TAG_COMPOUND);
        log.debug(plugin, UTIL_NAME, SERVER_QUEST_DATA_WRITE_DATA.getDeclaringClass().getName() + "." + SERVER_QUEST_DATA_WRITE_DATA.getName() + "()");
    }

    /**
     * 获取玩家当前的任务nbt
     * @param player 玩家
     * @return byte[]
     */
    public static byte[] getPlayerQuestNbtData(Player player) {
        Object nbt = NMSUtil.newNbtTagCompound();
        String playerName = player.getName();
        // nbt传入writeData,将赋值为服务器当前读取到的玩家任务数据nbt
        ReflectionUtil.invokeMethod(SERVER_QUEST_DATA_WRITE_DATA, getPlayerData(player), nbt);
        log.debug(plugin, "FTBQuestUtil.getPlayerQuestNbtData ===> 玩家 {} 当前任务进度 &e{}", playerName, nbt);
        // 反序列化nbt -> byte[]
        return NMSUtil.nbt2Bytes(nbt);
    }

    /**
     * 获取玩家的SeverQuestData实例
     * @param player 玩家
     * @return ServerQuestData实例
     */
    public static Object getPlayerData(Player player) {
        Object playerTeam = FTBLibUtil.getPlayerTeam(player);
        return ReflectionUtil.invokeStaticMethod(SERVER_QUEST_DATA_GET, playerTeam);
    }

    /**
     * 写入玩家任务数据
     * @param player 玩家
     * @param nbtData nbt数据
     */
    public static void setPlayerQuest(Player player, byte[] nbtData) {

        String playerName = player.getName();

        log.debug(plugin, "FTBQuestUtil.setPlayerQuest ===> 开始同步玩家 {} 任务数据", playerName);

        FTBLibUtil.postTeamCreate(player);
        log.debug(plugin, "teamCreate完成");

        Object nbt = NMSUtil.bytes2Nbt(nbtData);
        log.debug(plugin, "任务数据 ===> {}", nbt);
        Object playerData = getPlayerData(player);
        log.debug(plugin, "获取playerData完成");

        log.debug(plugin, "非空验证 ===> SERVER_QUEST_DATA_READ_DATA: {0}, playerData: {1}, nbt: {2}",
                Objects.nonNull(SERVER_QUEST_DATA_READ_DATA),
                Objects.nonNull(playerData),
                Objects.nonNull(nbt));

        ReflectionUtil.invokeMethod(SERVER_QUEST_DATA_READ_DATA, playerData, nbt);

        FTBLibUtil.postLogin(player);
        log.debug(plugin, "login事件完成");

        ReflectionUtil.invokeMethod(SERVER_QUEST_DATA_MARK_DIRTY, getPlayerData(player));
        log.debug(plugin, "markDirty完成");

        log.debug(plugin, "FTBQuestUtil.setPlayerQuest ===> 玩家 {} 任务数据同步完毕", playerName);
    }

    public static void init() {
        log.debug(plugin, "&eFTBQuestUtil初始化完毕");
    }



}
